package com.sslite.reports.effectsofhighvolumereport;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.josql.Query;
import org.josql.QueryResults;

import com.sslite.model.ChartApplet;
import com.sslite.model.IntraDayStructure;
import com.sslite.model.MetaData;
import com.sslite.util.ReportUtil;
import com.sslite.util.SSLiteProperties;
import com.sslite.util.Utility;

public class EffectsOfHighVolumeReport implements Runnable{
	private MetaData metaData;
	private ReportUtil reportUtil;

	final static List<Double> Y_LABEL_POS = Arrays.asList(new Double[]{0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95});

	public EffectsOfHighVolumeReport(MetaData metaData) {
		this.metaData = metaData;
		this.reportUtil = new ReportUtil(metaData);
	}

	public MetaData getMetaData() {
		return metaData;
	}

	public void setMetaData(MetaData metaData) {
		this.metaData = metaData;
	}
	
	@Override
	public void run(){
		try{
			generateReport();
		}
		catch(Exception e){
			System.out.println( "EffectsOfHighVolumeReport: Exception while generating report for " +this.getMetaData().getSymbol() );
			e.printStackTrace();
		}
	}

	private void generateReport() throws Exception{

		final List<IntraDayStructure> idsList = reportUtil.getIntraDayStructureList();
		if( idsList != null && !idsList.isEmpty() ){
			QueryResults qrHighVolume = Query.parseAndExec(SSLiteProperties.EFFECTSOFHIGHVOLUME_JOSQL_QUERY.getValue(), new ArrayList<IntraDayStructure>(idsList) );
			List<IntraDayStructure> results = qrHighVolume.getResults();
			final List<Integer> highVolumeIndices = new ArrayList<Integer>();
			if( results != null && !results.isEmpty() ){
				for( final IntraDayStructure ids : results ){
					highVolumeIndices.add( ids.getIndex() );
				}
			}
	
			final StringBuilder sbDates = new StringBuilder();
			final List<Long> volumeList = new ArrayList<Long>();
			final List<Double> closeList = new ArrayList<Double>();
			
			for( final IntraDayStructure ids : idsList ){
				String ohlc = "(OHLC:" +ids.getOpen()+" "+ids.getHigh()+" "+ids.getLow()+" "+ids.getClose()+ ")\\n";
				sbDates.append(",").append(Utility.getStrDate(new Date(ids.getTime()), "MM/dd/yyyy hh:mma") +" "+ohlc);
				volumeList.add( ids.getVolume() );
				closeList.add( ids.getClose() );
			}
			
			// Labels
			final List<String> labels = new ArrayList<String>();
			int yIndex = 0;
			for( final Integer index : highVolumeIndices ){
				if( yIndex == Y_LABEL_POS.size() ){
					yIndex = 0;
				}
	
				final IntraDayStructure ids = idsList.get( index-1 );
				String strChange = "";
				try{
					final IntraDayStructure idsPrev = idsList.get( index-1 );
					final double change = Utility.round( ((ids.getClose() - idsPrev.getClose()) / idsPrev.getClose()) * 100.00 );
					strChange = Utility.round(change)+"%";
				}
				catch(Exception e){
					strChange = "N/A";
				}
				
				String desc = "Time:"+Utility.getStrDate(new Date(ids.getTime()), "hh:mma")+",\\nChange: " +strChange+ ",\\nOHLC:" +ids.getOpen()+ ","+ ids.getHigh()+ ","+ ids.getLow()+ ","+ ids.getClose();
				desc += ",\\nVxC:" +Utility.getFormattedInteger(ids.getClose()*ids.getVolume());
				String label = desc.replaceAll(",", ".")+",0.45," +Y_LABEL_POS.get(yIndex++)+ "," +(index-1)+",0";
				labels.add(label);
			}
	
			final ChartApplet chartApplet = new ChartApplet( metaData.getSymbol(), 900, 350 );
			chartApplet.setParamValue("chartTitle", metaData.getSymbol());
			chartApplet.setParamValue("sampleValues_0", closeList.toString().replaceAll("\\[|\\]", "").replaceAll(" ", "")); //sbCloseData.substring(1));
			//chartApplet.setParamValue("sampleValues_1", volumeList.toString().replaceAll("\\[|\\]", "").replaceAll(" ", ""));
	
			chartApplet.setParamValue("sampleLabels", sbDates.substring(1));
			chartApplet.setParamValue("sampleHighlightSize", "4");
			chartApplet.setParamValue("sampleScrollerOn", "true");
			//chartApplet.setParamValue("visibleSamples", "0,390");
	
			chartApplet.setParamValue("lowerRange_2", Collections.min(closeList).toString());
			for(int i=0; i<labels.size(); i++){
				chartApplet.setParamValue("label_"+i, labels.get(i));
			}
	
			final StringBuilder sbTmp = new StringBuilder();
			sbTmp.append( "<a href='http://www.google.com/finance?q=" +metaData.getSymbol()+ "' target='_new' " +(metaData.isInSogotradeShortList() ? "style='background-color:#00FF00'" : "")+ ">" +metaData.getSymbol()+ "</a> " );
			sbTmp.append( "MktCap: " );
			
			if( metaData.getSharesOutstanding() != null ){
				sbTmp.append("$" +Utility.getFormattedInteger( metaData.getSharesOutstanding() * idsList.get(idsList.size()-1).getClose() ) );
			}else{
				sbTmp.append("N/A");
			}
			sbTmp.append( "<BR>" + chartApplet.getChartAppletHTML() +"\n\n" );

			// ****************** Add Stats as comments ******************* //
			if( !highVolumeIndices.isEmpty() ){
				sbTmp.append( "<!-- Symbol|Pump@|PumpDate (MM/DD/YY HH:mm)|PumpSize$|MinAfterPump|MinAfterPump%|MaxAfterPump|MaxAfterPump%|MktCapAtPump|LastClose|AgeOfPump(Days) -->\n" );
				for( final Integer index : highVolumeIndices ){
					final List<IntraDayStructure> subList = idsList.subList(index, idsList.size());

					if( subList != null && !subList.isEmpty() ){
						final List<IntraDayStructure> rsLow = Query.parseAndExec("SELECT * FROM com.sslite.model.IntraDayStructure order by low asc limit 1", new ArrayList<IntraDayStructure>(subList) ).getResults();
						final List<IntraDayStructure> rsHigh = Query.parseAndExec("SELECT * FROM com.sslite.model.IntraDayStructure order by high desc limit 1", new ArrayList<IntraDayStructure>(subList) ).getResults();

						Double min = rsLow.get(0).getLow();
						Double max = rsHigh.get(0).getHigh();
	
						final IntraDayStructure idsPump = idsList.get( index-1 );
		
						final double changeToMin = Utility.round( ((min - idsPump.getClose()) / idsPump.getClose()) * 100.00 );
						final double changeToMax = Utility.round( ((max - idsPump.getClose()) / idsPump.getClose()) * 100.00 );
		
						String mktCapAtPump = "N/A";
						final Double lastClose = idsList.get(idsList.size()-1).getClose();
						if( metaData.getSharesOutstanding() != null ){
							mktCapAtPump = "$" +Utility.getFormattedInteger( metaData.getSharesOutstanding() * idsPump.getClose() );
						}
						
						sbTmp.append( "<!-- " +metaData.getSymbol()+ "|" +idsPump.getClose()+"|"+Utility.getStrDate(new Date(idsPump.getTime()), "MM/dd/yyyy hh:mma")+ "|$" +Utility.getFormattedInteger(idsPump.getClose()*idsPump.getVolume())+ "|" +min+ "|" +Utility.round(changeToMin)+ "%|" +max+ "|" +Utility.round(changeToMax)+ "%|" +mktCapAtPump+ "|" +lastClose+ "|" +Utility.getDaysDiffBetween(new Date(idsPump.getTime()), new Date())+ " -->\n" );
					}
				}
			}
			// *************************************************** //

			
			// Checks for Qualified only.
			boolean bQualified = false;
			if( !highVolumeIndices.isEmpty() ){
				bQualified = true;
			}
			
			if( bQualified ){
				Utility.saveContent(SSLiteProperties.TMP_RPT_FOLDER_EFFECTSOFHIGHVOLUME.getValue()+"q_"+metaData.getSymbol()+".html", sbTmp.toString());
			}else{
				Utility.saveContent(SSLiteProperties.TMP_RPT_FOLDER_EFFECTSOFHIGHVOLUME.getValue()+"uq_"+metaData.getSymbol()+".html", sbTmp.toString());
			}
		}else{
			System.out.println( "EffectsOfHighVolumeReport: No data available to generate report for " +metaData.getSymbol() );
		}
	}

}
